<?php

namespace App\Console\Commands;

use App\Consts;
use App\Project;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class ExportFormalReviewPassedProjects extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'export-formal-review-passed-projects';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $awardId2AwardName = [];
        $awards = config('vars.awards');
        foreach ($awards as $awardId => $award) {
            $awardId2AwardName[$awardId] = $award['name'];
        }
        $awardIds = array_keys($awardId2AwardName);

        $awardId2OutputProjectHeaders = [
            Consts::AWARD_TYPE_PROGRESS => ['成果名称', '完成人', '完成单位'],
            Consts::AWARD_TYPE_TALENT => ['候选人', '所在单位'],
        ];

        $statusIdsForFormalReviewUnpassed = [
            Project::STATUS_FORMAL_REVIEW_FILL_APPLICATION, Project::STATUS_FORMAL_REVIEW_RETURNED_TO_FILL
        ];
        $rawProjects = Project::whereNotIn('status_id', $statusIdsForFormalReviewUnpassed)
            ->select('id', 'award_id')
            ->get();

        $awardId2OutputProjects = [];
        foreach ($awardIds as $awardId) {
            $awardId2OutputProjects[$awardId] = [];
        }
        foreach ($rawProjects as $rawProject) {
            $awardId = $rawProject->award_id;
            try {
                $outputProject = $this->convertRawProjectToOutputProject($rawProject);
            } catch (\Throwable $e) {
                echo "变换项目 #{$rawProject->id} 失败\n";
                exit(-1);
            }
            $awardId2OutputProjects[$awardId][] = $outputProject;
        }

        foreach ($awardId2AwardName as $awardId => $awardName) {
            $outputProjectsSavePath = __DIR__ . "/通过形式审查项目名单-$awardName.csv";
            $outputProjectsOfThisAward = $awardId2OutputProjects[$awardId];
            $outputProjectHeadersOfThisAward = $awardId2OutputProjectHeaders[$awardId];
            array_unshift($outputProjectsOfThisAward, $outputProjectHeadersOfThisAward);
            $this->write_csv_file($outputProjectsSavePath, $outputProjectsOfThisAward);
            echo "$awardName: $outputProjectsSavePath\n";
        }
    }

    /**
     * @param $rawProject
     * @return array
     * @throws \Throwable
     */
    private function convertRawProjectToOutputProject($rawProject)
    {
        $awardId = $rawProject->award_id;
        $projectFormDataRecord = DB::table('application_form_data')
            ->where('id', $rawProject->id)
            ->first();

        $formData = json_decode($projectFormDataRecord->form_data);
        if ($awardId == Consts::AWARD_TYPE_PROGRESS) {
            $basicSituation = $formData->basic_situation;
            return [
                $basicSituation->project_name,
                $basicSituation->complete_people,
                $basicSituation->complete_companies,
            ];
        } elseif ($awardId == Consts::AWARD_TYPE_TALENT) {
            $basic = $formData->basic;
            return [
                $basic->name,
                $basic->company,
            ];
        } else {
            throw new \RuntimeException("未知奖项类型 $awardId");
        }
    }

    /**
     * @param $path
     * @param bool $isDir
     * @return bool true on success or false on failure.
     */
    private function ensureDirExists($path, $isDir = true)
    {
        $dir = $isDir ? $path : dirname($path);
        return is_dir($dir) ? true : mkdir($dir, 0777, true);
    }

    /**
     * @param $path
     * @param $items
     * @return bool 是否成功
     */
    private function write_csv_file($path, $items)
    {
        if (!$this->ensureDirExists($path, false)) {
            return false;
        };
        $fout = fopen($path, 'w');
        if ($fout === false) {
            return false;
        }
        foreach ($items as $item) {
            fputcsv($fout, $item);
        }
        return fclose($fout);
    }
}
